package ws

import (
	"encoding/json"
	"log"
	"sync"
)

// Hub 维护活动客户端的集合并广播消息
type Hub struct {
	// 注册的客户端
	clients map[uint]*Client

	// 广播消息通道
	Broadcast chan []byte

	// 注册请求通道
	Register chan *Client

	// 注销请求通道
	Unregister chan *Client

	// 互斥锁
	mu sync.RWMutex
}

// NewHub 创建一个新的Hub
func NewHub() *Hub {
	return &Hub{
		Broadcast:  make(chan []byte),
		Register:   make(chan *Client),
		Unregister: make(chan *Client),
		clients:    make(map[uint]*Client),
	}
}

// Run 启动Hub
func (h *Hub) Run() {
	for {
		select {
		case client := <-h.Register:
			h.mu.Lock()
			h.clients[client.ID] = client
			h.mu.Unlock()

			// 广播用户上线消息
			statusMsg := Message{
				Type: "user_status",
				Data: map[string]interface{}{
					"user_id": client.ID,
					"online":  true,
				},
			}
			if msgBytes, err := json.Marshal(statusMsg); err == nil {
				h.BroadcastToAll(msgBytes)
			}

		case client := <-h.Unregister:
			h.mu.Lock()
			if _, ok := h.clients[client.ID]; ok {
				delete(h.clients, client.ID)
				client.Close()

				// 广播用户下线消息
				statusMsg := Message{
					Type: "user_status",
					Data: map[string]interface{}{
						"user_id": client.ID,
						"online":  false,
					},
				}
				if msgBytes, err := json.Marshal(statusMsg); err == nil {
					h.BroadcastToAll(msgBytes)
				}
			}
			h.mu.Unlock()

		case message := <-h.Broadcast:
			var msg Message
			if err := json.Unmarshal(message, &msg); err != nil {
				log.Printf("error unmarshaling broadcast message: %v", err)
				continue
			}

			// 广播给所有用户
			h.BroadcastToAll(message)
		}
	}
}

// GetClient 获取指定ID的客户端
func (h *Hub) GetClient(id uint) *Client {
	h.mu.RLock()
	defer h.mu.RUnlock()
	return h.clients[id]
}

// BroadcastToAll 广播消息给所有客户端
func (h *Hub) BroadcastToAll(message []byte) {
	h.mu.RLock()
	defer h.mu.RUnlock()

	for _, client := range h.clients {
		client.SendMessage(message)
	}
}
